package net.esj.basic.interceptor;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.esj.basic.core.engine.support.message.MessageProvidersFactory;
import net.esj.basic.core.view.ResponseStatusCode;
import net.esj.basic.utils.StringUtils;
import net.esj.basic.utils.Validators;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsStatics;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * 异常处理及日志记录
 * @author Administrator
 *
 */
public class ExceptionInterceptor extends AbstractInterceptor implements ResponseStatusCode{

	/**
	 * 
	 */
	private static final long serialVersionUID = -2616172446444661778L;
	
	protected static final Logger logger = Logger.getLogger(ExceptionInterceptor.class);
	
	private int statusCode = 500;
	private String contentType = "text";
	
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		String result = "error";
		try {
			result = invocation.invoke();
		}catch (Throwable ex) {
			return publishException(invocation,ex);
			//throw new EsjRuntimeException("程序错误！", ex);
		}
		return result;
	}
	
	private String buildErrors(Map<String,List<String>> fieldErrors,Collection<String> actionErrors){
		StringBuilder sb = new StringBuilder();
		for(Map.Entry<String, List<String>> entry: fieldErrors.entrySet()){
			for(String str : entry.getValue()){
				sb.append(str).append(",");
			}
		}
		for(String str : actionErrors){
			sb.append(str).append(",");
		}
		return sb.toString();
	}

	private String publishException(ActionInvocation invocation,Throwable ex){
		ex.printStackTrace();
		logger.error(ex.toString());
		ActionContext actionContext = invocation.getInvocationContext();   
		HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);   
		HttpServletResponse response= (HttpServletResponse) actionContext.get(StrutsStatics.HTTP_RESPONSE);   
		
		
		if(Validators.isEmpty(invocation.getResultCode())){//没有返回code表示为AJAX操作
			writeJsonError(ex.getMessage(), request, response);
			return null;
		}else{
			return "error";
		}
	}
	
	private String publishException(ActionInvocation invocation,String exp){
		logger.error(exp);
		ActionContext actionContext = invocation.getInvocationContext();   
		HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);   
		HttpServletResponse response= (HttpServletResponse) actionContext.get(StrutsStatics.HTTP_RESPONSE);   
		if(Validators.isEmpty(invocation.getResultCode())){//没有返回code表示为AJAX操作
			writeJsonError(MessageProvidersFactory.getInstance().getMessage(null, exp,null, Locale.getDefault()), request, response);
			return null;
		}else{
			return "error";
		}
	}
	
	private void writeJsonError(String exp ,HttpServletRequest request,HttpServletResponse response){
		PrintWriter out =null;
		response.setContentType("text/"+contentType+";charset=UTF-8");
		response.setStatus(statusCode);
		try {
			out = response.getWriter();
			out.print(exp);
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if (out != null) {
				out.close();
			}
		}
	}

	public void setStatusCode(int statusCode) {
		if(statusCode>0){
			this.statusCode = statusCode;
		}
	}

	public void setContentType(String contentType) {
		if(StringUtils.hasText(contentType)){
			this.contentType = contentType;
		}
	}

}
